package utils;

import graph.Edge;
import graph.Graph;
import graph.Vertex;

import java.io.File;

import javax.xml.bind.JAXBContext;
import javax.xml.bind.JAXBElement;
import javax.xml.bind.JAXBException;
import javax.xml.bind.Marshaller;

import jaxb.graphml.EdgeType;
import jaxb.graphml.GraphType;
import jaxb.graphml.NodeType;
import jaxb.graphml.ObjectFactory;

public class GraphMLGenerator<V, W> {

	private Graph<V, W> graph;
	private String outputPath;
	
	public GraphMLGenerator(Graph<V, W> g, String outputPath) {
		this.graph = g;
		this.outputPath = outputPath;
	}
	
	@SuppressWarnings("rawtypes")
	public void generateGraphML() {
		JAXBContext context = null;
		Marshaller marshaller = null;
		try {
			context = JAXBContext.newInstance("jaxb.graphml");
			marshaller = context.createMarshaller();
		} catch (JAXBException e) {
			e.printStackTrace();
		}
		jaxb.graphml.ObjectFactory factory = new ObjectFactory();
		GraphType graphType = factory.createGraphType();
		for(Vertex v : graph.getVertices()) {
			NodeType nodeType = factory.createNodeType();
			nodeType.setId(v.getName());
			graphType.getDataOrNodeOrEdge().add(nodeType);
		}
		for(Edge e : graph.getEdges()) {
			EdgeType edgeType = factory.createEdgeType();
			edgeType.setSource(e.getV1().getName());
			edgeType.setTarget(e.getV2().getName());
			graphType.getDataOrNodeOrEdge().add(edgeType);
		}
		JAXBElement<GraphType> graphElement = factory.createGraph(graphType);
		
		try {
			marshaller.marshal(graphElement, new File(outputPath));
		} catch (JAXBException e1) {
			// TODO Auto-generated catch block
			e1.printStackTrace();
		}
	}

	/**
	 * @return the graph
	 */
	public Graph<V, W> getGraph() {
		return graph;
	}

	/**
	 * @param graph the graph to set
	 */
	public void setGraph(Graph<V, W> graph) {
		this.graph = graph;
	}

	/**
	 * @return the outputPath
	 */
	public String getOutputPath() {
		return outputPath;
	}

	/**
	 * @param outputPath the outputPath to set
	 */
	public void setOutputPath(String outputPath) {
		this.outputPath = outputPath;
	}
}
